import "./index.scss";
import Fuse from "fuse.js";
import { getNormalPath } from "@/utils/common";
import { isHttp } from "@/utils/validate";
import usePermissionStore from "@/store/modules/permission";
import { RouteOption } from "vue-router";
import { ElSelect } from "element-plus";
import SvgIcon from "../SvgIcon/index";
export default defineComponent({
  props: {
    id: {
      type: String,
    },
  },
  setup(props) {
    type Router = Array<{
      path: string;
      title: string[];
    }>;

    const search = ref("");
    const options = ref<any>([]);
    const searchPool = ref<Router>([]);
    const show = ref(false);
    const fuse = ref();
    const headerSearchSelectRef = ref(ElSelect);
    const router = useRouter();
    const routes = computed(() => usePermissionStore().routes);

    const click = () => {
      show.value = !show.value;
      if (show.value) {
        headerSearchSelectRef.value && headerSearchSelectRef.value.focus();
      }
    };
    const close = () => {
      headerSearchSelectRef.value && headerSearchSelectRef.value.blur();
      options.value = [];
      show.value = false;
    };
    const change = (val: any) => {
      const path = val.path;
      if (isHttp(path)) {
        // http(s):// 路径新窗口打开
        const pindex = path.indexOf("http");
        window.open(path.substr(pindex, path.length), "_blank");
      } else {
        router.push(path);
      }
      search.value = "";
      options.value = [];
      nextTick(() => {
        show.value = false;
      });
    };
    const initFuse = (list: Router) => {
      fuse.value = new Fuse(list, {
        shouldSort: true,
        threshold: 0.4,
        location: 0,
        distance: 100,
        minMatchCharLength: 1,
        keys: [
          {
            name: "title",
            weight: 0.7,
          },
          {
            name: "path",
            weight: 0.3,
          },
        ],
      });
    };
    // Filter out the routes that can be displayed in the sidebar
    // And generate the internationalized title
    const generateRoutes = (
      routes: RouteOption[],
      basePath = "",
      prefixTitle: string[] = []
    ) => {
      let res: Router = [];
      routes.forEach((r) => {
        // skip hidden router
        if (!r.hidden) {
          const p =
            r.path.length > 0 && r.path[0] === "/" ? r.path : "/" + r.path;
          const data = {
            path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path,
            title: [...prefixTitle],
          };
          if (r.meta && r.meta.title) {
            data.title = [...data.title, r.meta.title];
            if (r.redirect !== "noRedirect") {
              // only push the routes with title
              // special case: need to exclude parent router without redirect
              res.push(data);
            }
          }
          // recursive child routes
          if (r.children) {
            const tempRoutes = generateRoutes(
              r.children,
              data.path,
              data.title
            );
            if (tempRoutes.length >= 1) {
              res = [...res, ...tempRoutes];
            }
          }
        }
      });
      return res;
    };
    const querySearch = (query: string) => {
      if (query !== "") {
        options.value = fuse.value.search(query);
      } else {
        options.value = [];
      }
    };

    onMounted(() => {
      searchPool.value = generateRoutes(routes.value);
    });

    watchEffect(() => {
      searchPool.value = generateRoutes(routes.value);
    });

    watch(show, (value) => {
      if (value) {
        document.body.addEventListener("click", close);
      } else {
        document.body.removeEventListener("click", close);
      }
    });

    watch(searchPool, (list) => {
      initFuse(list);
    });
    return () => (
      <div class={`header-search ${show.value ? "show" : ""}`} id={props.id}>
        <div
          onClick={(e: any) => {
            e.stopPropagation();
            click();
          }}
        >
          <SvgIcon className="search-icon" iconClass="search" />
        </div>
        <el-select
          ref="headerSearchSelectRef"
          v-model={search}
          remote-method={querySearch}
          filterable
          default-first-option
          remote
          placeholder="Search"
          class="header-search-select"
          onChange={change}
        >
          {options.value.map((option: any, index: any) => (
            <el-option
              key={option.item.path}
              value={option.item}
              label={option.item.title.join(" > ")}
            />
          ))}
        </el-select>
      </div>
    );
  },
});
